﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

using IETTortak;

using ALV = AsyncListView.AsyncListView;

namespace IETTdb_Regex_SQL
{
    public partial class Form1 : Form
    {
        const string urlHatList = "http://www.iett.gov.tr/";


        public Form1()
        {
            InitializeComponent();
        }

        private List<string> GetGuzHTMLList()
        {
            return new List<string>(Directory.GetFiles(txtDataDirectory.Text, "*.guz.htm"));
        }

        private void GüzergahlarıTaraVeritabanınaEkle()
        {
            alvİşlemler.AddRow("dosyalar", "guz.htm dosyaları taranıyor");
            alvİşlemler.UpdateRowState("dosyalar", ALV.IconKey.Processing);
            List<string> guzHtmDosyalar = GetGuzHTMLList();
            alvİşlemler.UpdateRowState("dosyalar", ALV.IconKey.Success);
            foreach (string s in guzHtmDosyalar)
            {
                alvİşlemler.AddRow(Path.GetFileName(s), string.Format("Hat dosyası taranıyor: {0}", Path.GetFileName(s)));
            }

            List<Guzergah> lstGuzergah = new List<Guzergah>();

            foreach (string s in guzHtmDosyalar)
            {
                alvİşlemler.UpdateRowState(Path.GetFileName(s), AsyncListView.AsyncListView.IconKey.Processing);
                //lstGuzergah.Add(GuzergahParser.Parse(File.ReadAllText(s)));
                alvİşlemler.UpdateRowState(Path.GetFileName(s), AsyncListView.AsyncListView.IconKey.Success);
            }
        }

        private List<Guzergah> lstGuzergah = new List<Guzergah>();
        private List<Service> lstService = new List<Service>();

        private void button1_Click(object sender, EventArgs e)
        {
            AsyncGuzergahParser agp = new AsyncGuzergahParser(Directory.GetFiles(txtDataDirectory.Text, "*.guz.htm"));
            alvİşlemler.AddRow("güzergahlar", string.Format("{0} adet güzergah bulundu, taranıyor.", agp.GüzergahCount), ALV.IconKey.Information);

            agp.Ekle += new AsyncGuzergahParser.ALVEkle(agp_Ekle);
            agp.Hata += new AsyncGuzergahParser.ALVHataHandler(agp_Hata);
            agp.GuzergahEkle += new AsyncGuzergahParser.GuzergahEkleHandler(agp_GuzergahEkle);
            agp.Processing += new AsyncGuzergahParser.ALVDurumDeğiştiHandler(agp_Processing);
            agp.Success += new AsyncGuzergahParser.ALVDurumDeğiştiHandler(agp_Success);
            agp.UpdateProgress += new AsyncGuzergahParser.UpdateProgressHandler(agp_UpdateProgress);
            agp.GüzergahlarTarandı += new AsyncGuzergahParser.GuzergahlarTarandıHandler(agp_GüzergahlarTarandı);
            agp.Start();
        }

        void agp_UpdateProgress(string key, int tamamlanan, int tümü)
        {
            alvİşlemler.UpdateProgress(key, (int)(100.0 * tamamlanan / tümü));
        }

        void agp_GüzergahlarTarandı()
        {
            alvİşlemler.AddRow("bitti", "Güzergahlar tarandı.", AsyncListView.AsyncListView.IconKey.Success);

            string gdhKey = Guid.NewGuid().ToString();
            alvİşlemler.AddRow(gdhKey, "Güzergahlar veritabanına ekleniyor.", AsyncListView.AsyncListView.IconKey.Processing, true);
            try
            {
                GuzergahDatabaseHelper gdh = new GuzergahDatabaseHelper(gdhKey);
                gdh.UpdateProgress += new GuzergahDatabaseHelper.UpdateProgressHandler(agp_UpdateProgress);
                gdh.AddGuzergahListToDB(lstGuzergah);
                alvİşlemler.UpdateRowState(gdhKey, ALV.IconKey.Success);
            }
            catch (Exception ex)
            {
                alvİşlemler.UpdateRowState(gdhKey, ALV.IconKey.Failure, ex.Message);
            }
        }

        void agp_Hata(string key, string message)
        {
            alvİşlemler.UpdateRowState(key, AsyncListView.AsyncListView.IconKey.Failure, message);
        }

        void agp_Success(string key)
        {
            alvİşlemler.UpdateRowState(key, AsyncListView.AsyncListView.IconKey.Success);
        }

        void agp_Processing(string key)
        {
            alvİşlemler.UpdateRowState(key, AsyncListView.AsyncListView.IconKey.Processing);
        }

        void agp_GuzergahEkle(Guzergah g)
        {
            if (g == null)
                return;
            lock (lstGuzergah)
            {
                lstGuzergah.Add(g);
            }
        }

        void agp_Ekle(string key, string message)
        {
            alvİşlemler.AddRow(key, message, AsyncListView.AsyncListView.IconKey.Processing, true);
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            label4.Text = lstGuzergah.Count.ToString();
        }

        private int servisCount;
        private void button2_Click(object sender, EventArgs e)
        {
            List<string> lst = new List<string>(Directory.GetFiles(txtDataDirectory.Text, "*.htm"));
            AsyncServiceParser asp = new AsyncServiceParser(lst.FindAll(delegate(string s) { return !s.EndsWith(".guz.htm"); }).ToArray());

            servisCount = asp.ServiceCount;

            alvİşlemler.AddRow("servisler", string.Format("{0} adet hat bulundu, taranıyor.", servisCount), ALV.IconKey.Information, true);


            asp.Ekle += new AsyncServiceParser.ALVEkle(agp_Ekle);
            asp.Hata += new AsyncServiceParser.ALVHataHandler(agp_Hata);
            asp.ServiceEkle += new AsyncServiceParser.ServiceEkleHandler(asp_ServiceEkle);
            asp.Processing += new AsyncServiceParser.ALVDurumDeğiştiHandler(agp_Processing);
            asp.Success += new AsyncServiceParser.ALVDurumDeğiştiHandler(agp_Success);
            asp.UpdateProgress += new AsyncServiceParser.UpdateProgressHandler(agp_UpdateProgress);
            asp.ServicelerTarandı += new AsyncServiceParser.ServicelerTarandıHandler(asp_ServicelerTarandı);
            asp.Start();
        }

        void asp_ServicelerTarandı()
        {
            alvİşlemler.AddRow("bittiServis", "Hatlar tarandı.", AsyncListView.AsyncListView.IconKey.Information);

            string sdhKey = Guid.NewGuid().ToString();
            alvİşlemler.AddRow(sdhKey, "Hatlar veritabanına ekleniyor.", AsyncListView.AsyncListView.IconKey.Processing, true);
            try
            {
                ServiceDatabaseHelper sdh = new ServiceDatabaseHelper(sdhKey);
                sdh.UpdateProgress += new ServiceDatabaseHelper.UpdateProgressHandler(agp_UpdateProgress);
                sdh.AddServiceListToDB(lstService);
                alvİşlemler.UpdateRowState(sdhKey, ALV.IconKey.Success);
            }
            catch (Exception ex)
            {
                alvİşlemler.UpdateRowState(sdhKey, ALV.IconKey.Failure, ex.Message);
            }
        }


        void asp_ServiceEkle(Service s)
        {
            lock (lstService)
            {
                lstService.Add(s);
            }
            alvİşlemler.UpdateProgress("servisler", (int)(100.0 * lstService.Count / servisCount));
        }

        List<string> lstİndirilmişHatNo = new List<string>();

        private void button3_Click(object sender, EventArgs e)
        {
            if (Directory.Exists(txtDataDirectory.Text))
            {
                string[] files = Directory.GetFiles(txtDataDirectory.Text, "*.guz.htm");
                lstİndirilmişHatNo.Clear();
                for (int i = 0; i < files.Length; i++)
                    lstİndirilmişHatNo.Add(Path.GetFileNameWithoutExtension(Path.GetFileNameWithoutExtension(files[i])));                
            }
            else
                Directory.CreateDirectory("data");

            string gd = Guid.NewGuid().ToString();
            RJH.DownloadThread dt = new RJH.DownloadThread(gd, urlHatList);
            dt.ProgressCallback += new RJH.DownloadProgressHandler(dt_ProgressCallback);
            alvİşlemler.AddRow(Guid.NewGuid().ToString(), "İndirilmiş hat sayısı: " + lstİndirilmişHatNo.Count, AsyncListView.AsyncListView.IconKey.Information);
            alvİşlemler.AddRow(gd, dt.DownloadUrl, AsyncListView.AsyncListView.IconKey.Processing, true);
            dt.CompleteCallback += new RJH.DownloadCompleteHandler(dt_CompleteCallback);
            dt.Download();
        }

        void dt_ProgressCallback(string key, int bytesRead, int totalBytes)
        {
            alvİşlemler.UpdateProgress(key, (int)(100.0 * bytesRead / totalBytes));
        }

        List<string> lstHatlar = new List<string>();

        void dt_CompleteCallback(string key, byte[] dataDownloaded)
        {
            alvİşlemler.UpdateProgress(key, 100);
            alvİşlemler.UpdateRowState(key, AsyncListView.AsyncListView.IconKey.Success, string.Format("Downloaded: {0}", dataDownloaded.Length));
            //iett hat list is downloaded process it.
            lstHatlar = IETTHatListParser.ParseHatList(dataDownloaded);

            alvİşlemler.AddRow(Guid.NewGuid().ToString(), "IETT hat sayısı: " + lstHatlar.Count, AsyncListView.AsyncListView.IconKey.Information);

            if (!chkTümünüİndir.Checked)
            {
                foreach (string s in lstİndirilmişHatNo)
                    if (lstHatlar.Contains(s) && (!chkSorunlu.Checked || (chkSorunlu.Checked && URLEncode(s) == s)))
                        lstHatlar.Remove(s);
                        
            }
            alvİşlemler.AddRow(Guid.NewGuid().ToString(), "İndirilecek hat sayısı: " + lstHatlar.Count, AsyncListView.AsyncListView.IconKey.Information);
        }

        private void button4_Click(object sender, EventArgs e)
        {
            AsyncHTMLDownloader ahd = new AsyncHTMLDownloader(lstHatlar.ToArray());
            ahd.Dosyalarİndirildi += new AsyncHTMLDownloader.DosyalarİndirildiHandler(ahd_Dosyalarİndirildi);
            ahd.Ekle += new AsyncHTMLDownloader.ALVEkle(agp_Ekle);
            ahd.Hata += new AsyncHTMLDownloader.ALVHataHandler(agp_Hata);
            ahd.HTMLEkle += new AsyncHTMLDownloader.HTMLEkleΗandler(ahd_HTMLEkle);
            ahd.Processing += new AsyncHTMLDownloader.ALVDurumDeğiştiHandler(agp_Processing);
            ahd.Success += new AsyncHTMLDownloader.ALVDurumDeğiştiHandler(agp_Success);
            ahd.UpdateProgress += new AsyncHTMLDownloader.UpdateProgressHandler(agp_UpdateProgress);
            ahd.Start();
        }

        private string URLEncode(string s)
        {
            return s.Replace("Ş", "%DE").Replace("İ", "%DD").Replace("Ö", "%D6").Replace("Ç", "%C7").Replace("Ü", "%DC");
        }

        private string URLDecode(string s)
        {
            return s.Replace("%DE", "Ş").Replace("%DD", "İ").Replace("%D6", "Ö").Replace("%C7", "Ç").Replace("%DC", "Ü");
        }

        void ahd_HTMLEkle(string url, byte[] data)
        {
            // dosyayı overwrite olara
            if (url.Contains("BtnDetay"))
            {
                // güzergah listesi

                int hatNoStart = url.IndexOf("hatcode=") + 8;
                int hatNoEnd = url.IndexOf('&', hatNoStart);

                string hatNo = url.Substring(hatNoStart, hatNoEnd - hatNoStart);
                string hatHTML = Encoding.GetEncoding("iso-8859-9").GetString(data);                

                using (StreamWriter sw = new StreamWriter(Path.Combine(txtDataDirectory.Text, string.Format("{0}.guz.htm", URLDecode(hatNo))), false, Encoding.UTF8))
                {
                    sw.Write(hatHTML);
                    sw.Flush();
                    sw.Close();
                }
            }
            else
            {
                // saat listesi

                string hatNo = url.Substring(url.IndexOf("=") + 1);
                string hatHTML = Encoding.GetEncoding("iso-8859-9").GetString(data);

                using (StreamWriter sw = new StreamWriter(Path.Combine(txtDataDirectory.Text, string.Format("{0}.htm", URLDecode(hatNo))), false, Encoding.UTF8))
                {
                    sw.Write(hatHTML);
                    sw.Flush();
                    sw.Close();
                }
            }
        }

        void ahd_Dosyalarİndirildi()
        {
            alvİşlemler.AddRow(Guid.NewGuid().ToString(), "Hatlar indirildi.", AsyncListView.AsyncListView.IconKey.Information);
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }
    }
}
